﻿using GFluentCode.Entity;
using GFluentCode.ORM;
using GFluentCode.ORM.SqlServer;
using GFluentCode.Tools;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace GFluentCode.CodeMaker
{
    public partial class FrmMain : Form
    {
        string conn = "Data Source={0};Initial Catalog={1};User ID={2};password={3}";

        SqlServerORM _sqlOrm;

        List<GFluentTableEntity> _tables = new List<GFluentTableEntity>();

        string deskPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);

        string dbConfigPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config.xml");
        
        string xmlTestPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config2.xml");

        public FrmMain()
        {
            InitializeComponent();

            Load += (s, e) =>
            {
                TxtPath.Text = Path.Combine(deskPath, "GFluentCode");

                if (!File.Exists(dbConfigPath)) return;

                var dbModel= XmlHelper.Read<DbModel>(dbConfigPath);

                TxtDbAddr.Text = dbModel.DbAddr;
                TxtDbName.Text = dbModel.DbName;
                TxtUserName.Text = dbModel.UserName;
                TxtPwd.Text = DescEncryptHelper.Decrypt(dbModel.Password,"AsakuraY");
            };
        }

        private void BtnConnect_Click(object sender, EventArgs e)
        {
            var ds = TxtDbAddr.Text;
            var db = TxtDbName.Text;
            var user = TxtUserName.Text;
            var pwd = TxtPwd.Text;

            if (ds.GIsEmpty() || db.GIsEmpty() || user.GIsEmpty() || pwd.GIsEmpty())
            {
                MessageBox.Show("数据连接配置不能为空");
                return;
            }

            _sqlOrm = new SqlServerORM(conn.GToFormat(ds, db, user, pwd));
            
            LbTables.Items.Clear();

            var tns = _sqlOrm.QueryTableNames().Select(t => t.TableName).ToList();

            foreach (var item in tns)
            {
                LbTables.Items.Add(item);
            }

            TxtEntityNamespace.Text = $"{db}Entity";
            TxtORMNamespace.Text = $"{db}ORM";

            var dbConfig = new DbModel { DbAddr = ds, DbName = db, UserName = user, Password = DescEncryptHelper.Encrypt(pwd, "AsakuraY") };

            XmlHelper.Save<DbModel>(dbConfigPath,"config",dbConfig);
        }

        private void BtnDir_Click(object sender, EventArgs e)
        {
            var dr = FolderBrowser.ShowDialog();
            if (dr != DialogResult.OK) return;
            TxtPath.Text = FolderBrowser.SelectedPath;
        }

        private void BtnMake_Click(object sender, EventArgs e)
        {
            if (LbTables.SelectedItems.Count <= 0) return;

            var entityNS = TxtEntityNamespace.Text;
            var ormNS = TxtORMNamespace.Text;

            _tables.Clear();            

            foreach (var si in LbTables.SelectedItems)
            {
                _tables.Add(_sqlOrm.QueryTableEntity(si.ToString()));
            }

            CreateTabControl(TabEntity);
            CreateTabControl(TabORM);

            foreach (var table in _tables)
            {
                TabEntity.Write(table.TableName, table.ToEntityTemplate(entityNS));
                TabORM.Write(table.TableName, table.ToORMTemplate(entityNS, ormNS));
            }
        }

        private void BtnSave_Click(object sender, EventArgs e)
        {
            var path = TxtPath.Text;

            foreach (var table in _tables)
            {
                SaveFile(path, "Entity", table.TableName, "Entity", TabEntity);
                SaveFile(path, "ORM", table.TableName, "ORM", TabORM);
            }

            
        }
        

        #region tab

        void CreateTabControl(TabControl tab)
        {
            tab.TabPages.Clear();

            foreach (var table in _tables)
            {
                var tp = new TabPage(table.TableName);
                var txt = new TextBox { ScrollBars = ScrollBars.Both } ;
                txt.Name = $"Txt{table.TableName}{tab.Name.ToString().Replace("Tab", "")}";
                txt.Multiline = true;
                txt.Dock = DockStyle.Fill;
                tp.Controls.Add(txt);
                tab.TabPages.Add(tp);
            }
        }
        #endregion

        #region Save

        void SaveFile(string path, string type, string tableName, string ext, TabControl tab)
        {
            var myPath = Path.Combine(path, type);
            if (!Directory.Exists(myPath))
                Directory.CreateDirectory(myPath);
            var tp = tab.TabPages.Cast<TabPage>().First(x => x.Text.Equals(tableName));
            myPath = Path.Combine(myPath, tableName + ext + ".cs");
            File.AppendAllText(myPath, tp.Controls[0].Text);
        }


        #endregion

        private void BtnCustom_Click(object sender, EventArgs e)
        {
            var frm = new FrmCustomClass(_sqlOrm,TxtPath.Text);
            frm.ShowDialog();
        }

        private void BtnWebApi_Click(object sender, EventArgs e)
        {
            var frm = new FrmWebApi(TxtPath.Text);
            frm.ShowDialog();
        }

        private void BtnEncryptDbStr_Click(object sender, EventArgs e)
        {
            var ds = TxtDbAddr.Text;
            var db = TxtDbName.Text;
            var user = TxtUserName.Text;
            var pwd = TxtPwd.Text;

            var str = conn.GToFormat(ds, db, user, pwd);

            var key = RandomKeyHelper.GenerateRandomNumber(8);

            var enStr = DescEncryptHelper.Encrypt(str, key);

            enStr = key + enStr;

            Clipboard.SetText(enStr);
        }
    }
}
